package demo3;

import java.io.PrintStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;

public class MyReflect {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        //1.获取class字节码文件
        Class clazz = Class.forName("demo3.Student");

        /*//2.获取里面所有的方法对象（包括父类的公共方法）
        Method[] methods = clazz.getMethods();
        for (Method method : methods) {
            System.out.println(method);
        }*/

        /*//3.获取里面所有的方法对象(不获取父类，但可以获取本类中所有方法
        Method[] methods = clazz.getDeclaredMethods();
        for (Method method : methods) {
            System.out.println(method);
        }*/

        //获取指定单一方法
        Method m = clazz.getDeclaredMethod("eat", String.class);
        System.out.println(m);
        //因为有方法重载，所以要指定参数

        //获取方法修饰符
        int modifiers = m.getModifiers();
        System.out.println(modifiers);

        //获取方法名字
        String name = m.getName();
        System.out.println(name);

        //获取方法形参
        Parameter[] parameters = m.getParameters();
        for (Parameter parameter : parameters) {
            System.out.println(parameter);
        }

        //获取方法抛出的异常
        Class[] exceptionTypes = m.getExceptionTypes();
        for (Class exceptionType : exceptionTypes) {
            System.out.println(exceptionType);
        }

        //方法运行
        /*Method 类中用于创建对象
        * Object invoke(Object obj, Object... args): 运行方法
        * 参数一：用obj对象调用的方法
        * 参数二：调用方法传递的参数(如果是void就不写)
        * 返回值：方法的返回值（如果没有就不写）
        * */

        Student s = new Student();
        //参数一s：方法调用者
        //参数二"羊肉"：表示调用方法的时候传递的实际参数
        m.setAccessible(true);//记住这个方法是私有的
        m.invoke(s,"羊肉");
        //如果有返回值就接受，可以强制转换

    }
}
